//
//  JQFXHNetworkManager.swift
//  jiuzhoudai
//
//  Created by luxiaoyan on 2025/7/9.
//

import Foundation
import Moya
import CryptoKit
import SwiftyJSON
import CleanJSON

class JQFXHNetworkManager {
    
    static let shared = JQFXHNetworkManager()  // 单例模式，方便全局使用
    let provider = MoyaProvider<JQFXHBenddAPI>()  // MoyaProvider 实例
    let moliProvider = MoyaProvider<JQFXHMoliffAPI>()  // MoyaProvider 实例
    let shengrProvider = MoyaProvider<JQFXHShengreeAPI>()  // MoyaProvider 实例

    private let userDataCacheKey = "K_USER_DATA"
    private let serverInfoDataCacheKey = "K_SERVER_DATA"
    private let mobileTypeKey = "K_MOBILE"
    private let hasApplyNumber = "hasApplyNumber"

    
    var isLogin: Bool { return jqfxhCurrentUser != nil }
    
    var mobileType : Int = 0{
        didSet {
            UserDefaults.standard.set(mobileType, forKey: mobileTypeKey)
        }
    }
    
    var jqfxhCurrentUser: User? {
        didSet {
            if let jqfxhCurrentUser, let data = try? JSONEncoder().encode(jqfxhCurrentUser) {
                UserDefaults.standard.set(data, forKey: userDataCacheKey)
            } else {
                UserDefaults.standard.set(nil, forKey: userDataCacheKey)
            }
        }
    }
    
    var partnerId: Int { return currentServerInfo?.app_config.partner_id ?? 1 }

    
    var currentServerInfo: JQFXHServerddInfoData? {
        didSet {
            if let currentServerInfo, let data = try? JSONEncoder().encode(currentServerInfo) {
                UserDefaults.standard.set(data, forKey: serverInfoDataCacheKey)
            } else {
                UserDefaults.standard.set(nil, forKey: serverInfoDataCacheKey)
            }
        }
    }
    
    var hasApply: Bool {
        if let mobile = self.jqfxhCurrentUser?.mobile, let currentLoanedMobile = self.currentLoanedMobile {
            return currentLoanedMobile.contains(mobile)
        }
        return false
    }

    func jqfxhUpdatebbLoanedMobile() -> Void {
        let mobile = self.jqfxhCurrentUser?.mobile
        let mobileLong = UserDefaults.standard.string(forKey: hasApplyNumber) ?? ""
        if !mobileLong.contains(mobile ?? "") {
            let adddStr = mobileLong + (mobile ?? "")
            UserDefaults.standard.set(adddStr, forKey: hasApplyNumber)
            self.currentLoanedMobile = adddStr
        }
    }
    
    var currentLoanedMobile: String?
    
    
    private init() {
        if let data = UserDefaults.standard.data(forKey: userDataCacheKey) {
            jqfxhCurrentUser = try? CleanJSONDecoder().decode(User.self, from: data)
        }
        
        if let serverData = UserDefaults.standard.data(forKey: serverInfoDataCacheKey) {
            currentServerInfo = try? CleanJSONDecoder().decode(JQFXHServerddInfoData.self, from: serverData)
        }
                
        mobileType = UserDefaults.standard.integer(forKey: mobileTypeKey)
            
    }
    
    func md5(_ string: String) -> String {
        let digest = Insecure.MD5.hash(data: string.data(using: .utf8) ?? Data())
        return digest.map { String(format: "%02hhx", $0) }.joined()
    }
    
    func jqfxhAbnormalReprownot(param: [String: Any], request: String, mobile: String, code: Int) -> Void {

        let provider = JQFXHNetworkManager.shared.provider
        self.jqfxhRequest(provider: provider, target: .jqfxhAbnormannl(para: param, request: request, mobile: mobile, code: code)) { result in
            print(result)
        }
    }
    
    func jqfxhRequest<T: Decodable, Target: TargetType>(provider: MoyaProvider<Target>, target: Target, type: T.Type, completion: @escaping (Result<T, Error>) -> Void) {
        provider.request(target) { result in
            switch result {
            case .success(let response):
                do {
                    let json = JSON(response.data)
                    print("URL：\(target.path)\nresult:\(json)")
                    if let target = target as? JQFXHThirdErrorqqParams& TargetType, target.jqfxhIsqqError(json: json) {
                        JQFXHHUD.jqfxhShowxxText(target.jqfxhErrorssMsg(json: json))
                        
                        self.jqfxhAbnormalReprownot(param: ["params": self.jqfxhGetJsonString(dict: target.params), "result": json.rawString() ?? ""], request: target.path, mobile: target.mobile(), code: target.jqfxhErrorrrCode(json: json))
                        throw JQFXHNetworkError.businessError(code: target.jqfxhErrorrrCode(json: json), message: target.jqfxhErrorssMsg(json: json))
                    }
                    else if Target.self == JQFXHBenddAPI.self {
                        guard let code = json["error_code"].int, code == 0 else {
                            if !target.path.contains("report") {
                                JQFXHHUD.jqfxhShowxxText(json["error_msg"].stringValue)
                            }
                            throw JQFXHNetworkError.businessError(code: json["error_code"].intValue, message: json["error_msg"].stringValue)
                        }
                    }
                    guard let data = try? json["data"].rawData(), let item = try? CleanJSONDecoder().decode(type, from: data) else {
                        throw JQFXHNetworkError.decodingError
                    }
                    completion(.success(item))
                } catch let error {
                    completion(.failure(error))
                }
            case .failure(let error):
                completion(.failure(error))
            }
        }
    }
    
    func jqfxhGetJsonString(dict:[String : Any]) -> String {
        if let jsonData = try? JSONSerialization.data(withJSONObject: dict, options: []) {
            var jsonString = String(data: jsonData, encoding: .utf8)
            jsonString = jsonString?.replacingOccurrences(of: "\\", with: "")
            return jsonString ?? ""
        }
        return ""
    }
    
    func jqfxhRequest<Target: TargetType>(provider: MoyaProvider<Target>, target: Target, completion: @escaping (Result<JSON, Error>) -> Void) {
        provider.request(target) { result in
            switch result {
            case .success(let response):
                do {
                    let json = JSON(response.data)
                    print("URL：\(target.path)\nresult:\(json)")
                    if let target = target as? JQFXHThirdErrorqqParams& TargetType, target.jqfxhIsqqError(json: json) {
                        JQFXHHUD.jqfxhShowxxText(target.jqfxhErrorssMsg(json: json))
                        
                        self.jqfxhAbnormalReprownot(param: ["params": self.jqfxhGetJsonString(dict: target.params), "result": json.rawString() ?? ""], request: target.path, mobile: target.mobile(), code: target.jqfxhErrorrrCode(json: json))
                        throw JQFXHNetworkError.businessError(code: target.jqfxhErrorrrCode(json: json), message: target.jqfxhErrorssMsg(json: json))
                    }
                    else if Target.self == JQFXHBenddAPI.self {
                        guard let code = json["error_code"].int, code == 0 else {
                            if !target.path.contains("report") {
                                JQFXHHUD.jqfxhShowxxText(json["error_msg"].stringValue)
                            }
                            throw JQFXHNetworkError.businessError(code: json["error_code"].intValue, message: json["error_msg"].stringValue)
                        }
                    }
                    
                    completion(.success(json))
                } catch let error {
                    completion(.failure(error))
                }
                
            case .failure(let error):
                completion(.failure(error))
            }
        }
    }
}
